#include "image_query.h"
#include <limits.h> // Add this include for PATH_MAX

// 比较 FileInfo 结构体用于 qsort
static int compare_fileinfo_asc(const void *a, const void *b) {
    const FileInfo *fa = (const FileInfo *)a;
    const FileInfo *fb = (const FileInfo *)b;
    if (fa->start_time < fb->start_time) return -1;
    if (fa->start_time > fb->start_time) return 1;
    return 0;
}

static int compare_fileinfo_desc(const void *a, const void *b) {
    const FileInfo *fa = (const FileInfo *)a;
    const FileInfo *fb = (const FileInfo *)b;
    if (fa->start_time > fb->start_time) return -1;
    if (fa->start_time < fb->start_time) return 1;
    return 0;
}

// 从文件名提取时间戳 (假设文件名是纯数字或数字+.+扩展名)
static int get_timestamp_from_filename(const char *filename) {
    char timestamp_str[MAX_FILENAME_LEN];
    size_t i = 0;
    while (filename[i] != '\0' && filename[i] != '.' && i < MAX_FILENAME_LEN - 1) {
        if (!isdigit(filename[i])) {
            return -1; // 非数字字符，无效文件名格式
        }
        timestamp_str[i] = filename[i];
        i++;
    }
    timestamp_str[i] = '\0';

    if (i == 0) {
        return -1; // 空时间戳部分
    }

    char *endptr;
    long timestamp = strtol(timestamp_str, &endptr, 10);

    // 检查转换是否成功且消耗了所有数字
    if (*endptr != '\0') {
        return -1;
    }
   
    return (int)timestamp; // 注意：如果时间戳可能超过 int 范围，需要调整
}

int query_images(const QueryParameters *params, QueryResult *result, int type) {
    if (!params || !result || type < 0 || type > 1){
        return -1; // 无效参数
    }

    char filename[MAX_FILENAME_LEN] = IMAGE_PATH;

    if(type == 0){
        strcpy(filename, IMAGE_PATH);
    }
    else{
        strcpy(filename, VIDEO_PATH);
    }
    
    DIR *dir = opendir(filename);
    if (!dir) {
        perror("Failed to open directory");
        return -1;
    }

    struct dirent *entry;
    FileInfo *all_files = NULL;
    int capacity = 0;
    int count = 0;

    errno = 0; // 清除 errno 以便区分 readdir 结束和错误
    while ((entry = readdir(dir)) != NULL) {
        // 跳过 . 和 ..
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
            continue;
        }

        // printf("entry->d_name: %s\n", entry->d_name);
        // 尝试从文件名获取时间戳
        // int timestamp = get_timestamp_from_filename(entry->d_name);
        // if (timestamp == -1) {
        //     fprintf(stderr, "Skipping file with invalid name format: %s\n", entry->d_name);
        //     continue; // 跳过无效格式的文件名
        // }
        // 获取文件状态 (大小等) 和时间戳
        char full_path[MAX_FILENAME_LEN];
        snprintf(full_path, sizeof(full_path), "%s%s", filename, entry->d_name);
 
         struct stat st;
         if (stat(full_path, &st) == -1) {
             perror("Failed to get file status");
             fprintf(stderr, "Skipping file due to stat error: %s\n", entry->d_name);
             continue; // 跳过无法获取状态的文件
         }
 
         // 确保是普通文件 (可选，根据需要)
         if (!S_ISREG(st.st_mode)) {
             continue;
         }
 
         // 使用文件修改时间作为时间戳
         int timestamp = (int)st.st_mtime; // 注意：如果时间戳可能超过 int 范围，需要调整类型
         printf("timestamp: %d\n", timestamp);

        // 应用时间过滤
        if (timestamp < params->start_time || timestamp > params->end_time) {
            continue;
        }

        // // 获取文件状态 (大小等)
        // char full_path[PATH_MAX]; 
        // snprintf(full_path, sizeof(full_path), "%s%s", filename, entry->d_name);
     
        // struct stat st;
        // if (stat(full_path, &st) == -1) {
        //     perror("Failed to get file status");
        //     fprintf(stderr, "Skipping file due to stat error: %s\n", entry->d_name);
        //     continue; // 跳过无法获取状态的文件
        // }

        // // 确保是普通文件 (可选，根据需要)
        // if (!S_ISREG(st.st_mode)) {
        //     continue;
        // }

        // 动态扩展数组 all_files
        if (count >= capacity) {
            capacity = (capacity == 0) ? 32 : capacity * 2;
            FileInfo *temp = realloc(all_files, capacity * sizeof(FileInfo));
            if (!temp) {
                perror("Failed to allocate memory for file list");
                free(all_files);
                closedir(dir);
                return -1;
            }
            all_files = temp;
        }
        
        // 填充 FileInfo
        strncpy(all_files[count].filename, entry->d_name, MAX_FILENAME_LEN - 1);
        all_files[count].filename[MAX_FILENAME_LEN - 1] = '\0'; // 确保 null 终止
        all_files[count].size = (int)st.st_size; // 注意：如果文件大小可能超过 int，需调整
        all_files[count].start_time = timestamp;
        all_files[count].end_time = timestamp; // 对于图片，结束时间设为开始时间

        if(type == 1)//video
        { // 视频类型
            // 解析文件名格式：1745723667_1745723967.mp4
            char *underscore = strchr(entry->d_name, '_');
            if (!underscore) {
                fprintf(stderr, "Invalid video filename format: %s\n", entry->d_name);
                continue;
            }
            
            // 提取开始时间戳
            char start_time_str[MAX_FILENAME_LEN];
            size_t start_len = underscore - entry->d_name;
            if (start_len >= MAX_FILENAME_LEN) {
                fprintf(stderr, "Start time string too long in filename: %s\n", entry->d_name);
                continue;
            }
            
            strncpy(start_time_str, entry->d_name, start_len);
            start_time_str[start_len] = '\0';
            
            // 转换为整数
            char *endptr;
            all_files[count].start_time = (int)strtol(start_time_str, &endptr, 10);
            if (*endptr != '\0') {
                fprintf(stderr, "Invalid start time in filename: %s\n", entry->d_name);
                continue;
            }
            
            // 提取结束时间戳
            char *dot = strchr(underscore + 1, '.');
            if (!dot) {
                fprintf(stderr, "Invalid video filename format (missing extension): %s\n", entry->d_name);
                continue;
            }
            
            char end_time_str[MAX_FILENAME_LEN];
            size_t end_len = dot - (underscore + 1);
            if (end_len >= MAX_FILENAME_LEN) {
                fprintf(stderr, "End time string too long in filename: %s\n", entry->d_name);
                continue;
            }
            
            strncpy(end_time_str, underscore + 1, end_len);
            end_time_str[end_len] = '\0';
            
            // 转换为整数
            all_files[count].end_time = (int)strtol(end_time_str, &endptr, 10);
            if (*endptr != '\0') {
                fprintf(stderr, "Invalid end time in filename: %s\n", entry->d_name);
                continue;
            }
        }

        // Add debug print before incrementing count
        printf("-> Adding file %s to list. Current count = %d\n", entry->d_name, count);

        count++;
        errno = 0; // 为下一次 readdir 调用重置 errno
    }

    printf("count: %d, errno: %d, entry: %p\n", count, errno, entry);
    // Guard the access to all_files[0]
    if (count > 0 && all_files != NULL) { 
        printf("all_files[0].filename: %s\n", all_files[0].filename);
        printf("all_files[0].start_time: %d\n", all_files[0].start_time);
        printf("all_files[0].end_time: %d\n", all_files[0].end_time);
    } else {
        printf("No files found or all_files is NULL after loop.\n");
    }

    if (errno != 0 && entry == NULL) {
        perror("Error reading directory");
        free(all_files);
        closedir(dir);
        return -1;
    }

    closedir(dir);

    // 排序
    if (count > 0) {
        if (params->sort == SORT_BY_TIME_ASC) {
            qsort(all_files, count, sizeof(FileInfo), compare_fileinfo_asc);
        } else if (params->sort == SORT_BY_TIME_DESC) {
            qsort(all_files, count, sizeof(FileInfo), compare_fileinfo_desc);
        }
        // 可以添加其他排序方式的处理
    }

    // 填充结果结构体
    result->file_num = count;
    result->page_num = (count + FILES_PER_PAGE - 1) / FILES_PER_PAGE;
    if (result->page_num == 0) {
        result->page_num = 1; // 即使没有文件，也至少有1页（空的）
    }

    // 处理无效页码或超出范围的页码
    result->cur_page = params->page;
    if (result->cur_page < 1) {
        result->cur_page = 1;
    }
    if (result->cur_page > result->page_num) {
        result->cur_page = result->page_num;
    }

    // 计算当前页的起始索引和文件数
    int start_index = (result->cur_page - 1) * FILES_PER_PAGE;
    result->num = 0;
    if (start_index < count) {
        int end_index = start_index + FILES_PER_PAGE;
        if (end_index > count) {
            end_index = count;
        }
        result->num = end_index - start_index;
        memcpy(result->info, &all_files[start_index], result->num * sizeof(FileInfo));
    } else {
        // 如果请求的页码有效但超出了实际文件范围（发生在文件总数减少后），则当前页文件数为0
        result->num = 0;
    }

    // 释放临时分配的内存
    free(all_files);

    return 0; // 成功
}

// --- 示例 main 函数 (用于测试) ---
// #include <time.h>

// int main() {
//     // 准备测试环境 (如果 /mnt/img 不存在或没有权限，需要调整或模拟)
//     // system("mkdir -p /mnt/img");
//     // system("touch /mnt/img/1678886400.jpg");
//     // system("touch /mnt/img/1678886405.png");
//     // system("touch /mnt/img/1678886410.jpeg");
//     // system("touch /mnt/img/invalidname.txt");
//     // ... 创建更多文件 ...

//     QueryParameters params;
//     params.page = 1;                 // 请求第 1 页
//     params.sort = SORT_BY_TIME_ASC;  // 按时间升序
//     params.start_time = 0;           // 所有时间
//     params.end_time = (int)time(NULL); // 当前时间

//     QueryResult result;

//     printf("Querying page %d, sort %d, time [%d, %d]\n",
//            params.page, params.sort, params.start_time, params.end_time);

//     if (query_images(&params, &result) == 0) {
//         printf("Query successful.\n");
//         printf("Total matching files: %d\n", result.file_num);
//         printf("Total pages: %d\n", result.page_num);
//         printf("Current page: %d\n", result.cur_page);
//         printf("Files on this page: %d\n", result.num);

//         for (int i = 0; i < result.num; ++i) {
//             printf("  - File: %s, Size: %d, Time: %d\n",
//                    result.info[i].filename,
//                    result.info[i].size,
//                    result.info[i].start_time);
//         }
//     } else {
//         fprintf(stderr, "Query failed.\n");
//         return 1;
//     }

//     params.page = 2;                 // 请求第 1 页
//     params.sort = SORT_BY_TIME_ASC;  // 按时间升序
//     params.start_time = 0;           // 所有时间
//     params.end_time = (int)time(NULL); // 当前时间

//     printf("Querying page %d, sort %d, time [%d, %d]\n",
//            params.page, params.sort, params.start_time, params.end_time);

//     if (query_images(&params, &result) == 0) {
//         printf("Query successful.\n");
//         printf("Total matching files: %d\n", result.file_num);
//         printf("Total pages: %d\n", result.page_num);
//         printf("Current page: %d\n", result.cur_page);
//         printf("Files on this page: %d\n", result.num);

//         for (int i = 0; i < result.num; ++i) {
//             printf("  - File: %s, Size: %d, Time: %d\n",
//                    result.info[i].filename,
//                    result.info[i].size,
//                    result.info[i].start_time);
//         }
//     } else {
//         fprintf(stderr, "Query failed.\n");
//         return 1;
//     }

//     params.page = 3;                 // 请求第 1 页
//     params.sort = SORT_BY_TIME_DESC;  // 按时间升序
//     params.start_time = 0;           // 所有时间
//     params.end_time = (int)time(NULL); // 当前时间

//     printf("Querying page %d, sort %d, time [%d, %d]\n",
//            params.page, params.sort, params.start_time, params.end_time);

//     if (query_images(&params, &result) == 0) {
//         printf("Query successful.\n");
//         printf("Total matching files: %d\n", result.file_num);
//         printf("Total pages: %d\n", result.page_num);
//         printf("Current page: %d\n", result.cur_page);
//         printf("Files on this page: %d\n", result.num);

//         for (int i = 0; i < result.num; ++i) {
//             printf("  - File: %s, Size: %d, Time: %d\n",
//                    result.info[i].filename,
//                    result.info[i].size,
//                    result.info[i].start_time);
//         }
//     } else {
//         fprintf(stderr, "Query failed.\n");
//         return 1;
//     }


    // 测试第二页 (如果存在)
    // if (result.page_num > 1) {
    //     params.page = 2;
    //     printf("\nQuerying page %d...\n", params.page);
    //     if (query_images(&params, &result) == 0) {
    //         printf("Query successful.\n");
    //         printf("Files on this page: %d\n", result.num);
    //         for (int i = 0; i < result.num; ++i) {
    //              printf("  - File: %s, Size: %d, Time: %d\n",
    //                    result.info[i].filename,
    //                    result.info[i].size,
    //                    result.info[i].start_time);
    //         }
    //     } else {
    //          fprintf(stderr, "Query failed for page 2.\n");
    //     }
    // }

    // // 测试按时间降序
    // params.page = 1;
    // params.sort = SORT_BY_TIME_DESC;
    // printf("\nQuerying page %d, sort DESC...\n", params.page);
    //  if (query_images(&params, &result) == 0) {
    //     printf("Query successful.\n");
    //     printf("Files on this page: %d\n", result.num);
    //     for (int i = 0; i < result.num; ++i) {
    //          printf("  - File: %s, Size: %d, Time: %d\n",
    //                result.info[i].filename,
    //                result.info[i].size,
    //                result.info[i].start_time);
    //     }
    // } else {
    //      fprintf(stderr, "Query failed for DESC sort.\n");
    // }

    // // 测试特定时间范围 (假设文件名为 1678886405.png)
    // params.sort = SORT_BY_TIME_ASC;
    // params.start_time = 1678886405;
    // params.end_time = 1744786042;
    // printf("\nQuerying specific time %d...\n", params.start_time);
    // if (query_images(&params, &result) == 0) {
    //     printf("Query successful.\n");
    //     printf("Files on this page: %d\n", result.num);
    //     for (int i = 0; i < result.num; ++i) {
    //          printf("  - File: %s, Size: %d, Time: %d\n",
    //                result.info[i].filename,
    //                result.info[i].size,
    //                result.info[i].start_time);
    //     }
    // } else {
    //      fprintf(stderr, "Query failed for specific time.\n");
    // }


//     return 0;
// } 